package com.xuecheng.manage_course.config;

import org.apache.commons.io.IOUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) // 激活方法上的preAuthorize注解
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    // 公钥
    private static final String PUBLIC_KEY = "publickey.txt";

    // 定义JWTTokenStore,使用JWT令牌
    @Bean
    public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
        return new JwtTokenStore(jwtAccessTokenConverter);
    }

    // 定义JWT令牌
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setVerifierKey(getPublicKey());
        return jwtAccessTokenConverter;
    }

    /**
     * 加载publicKey
     * @return 字符串形式返回publickey文件的内容
     */
    private String getPublicKey() {
        InputStream resourceAsStream = ResourceServerConfig.class.getClassLoader().getResourceAsStream(PUBLIC_KEY);
        if (resourceAsStream != null) {
            try {
                return IOUtils.toString(resourceAsStream, StandardCharsets.UTF_8);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("加载" + PUBLIC_KEY + "失败");
                return null;
            }
        } else {
            System.out.println("加载" + PUBLIC_KEY + "失败");
            return null;
        }
    }

    /**
     * 排除一些不需要授权的路径 需要继承ResourceServerConfigurerAdapter
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        // 所有请求都必须认证
        http.authorizeRequests()
                .antMatchers("/doc.html",
                        "/webjars/**", "/swagger-resources/**", "/v2/api-docs/**", "/api-docs-ext/**",
                        "/swagger-ui.html").permitAll()
                .anyRequest().authenticated();
    }
}
